#include "CDxManager.h"

//constructor 
//
CDxManager::CDxManager(void)
{
	mp_d3d		= NULL;
	mp_d3ddv	= NULL;
	mp_di		= NULL;
	mp_KeyBoard = NULL;
}

//deconstrcutor
//
CDxManager::~CDxManager(void)
{
	Clear();
}

//Clear diretc3D variables
//
void CDxManager::Clear(void)
{
	if (mp_d3d != NULL)
	{
		mp_d3d->Release();
		mp_d3d = NULL;
	}

	if (mp_d3ddv != NULL)
	{
		mp_d3ddv->Release();
		mp_d3ddv = NULL;
	}

	if (mp_di != NULL)
	{
		mp_di->Release();
		mp_di = NULL;
	}

	if (mp_KeyBoard != NULL)
	{
		mp_KeyBoard->Unacquire();
		mp_KeyBoard->Release();
		mp_KeyBoard = NULL;
	}
}

//Init DirectObject and Device
//
void CDxManager::InitDirect(HWND hWnd, D3DFORMAT BackBufferFormat, int iWidth, int iHeight, bool bIsWindowed)
{
	mp_d3d=Direct3DCreate9(D3D_SDK_VERSION);
	if (mp_d3d == NULL)
	{
		MessageBox(NULL, "Can not create Direct3D Object!", "ERROR", MB_OK);
		return;
	}

	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));

	d3dpp.BackBufferCount	= 1;
	d3dpp.BackBufferFormat	= BackBufferFormat;
	d3dpp.BackBufferWidth	= iWidth;
	d3dpp.BackBufferHeight	= iHeight;
	d3dpp.hDeviceWindow		= hWnd;
	d3dpp.Windowed			= bIsWindowed;
	d3dpp.SwapEffect		= D3DSWAPEFFECT_DISCARD;

	mp_d3d->CreateDevice(	D3DADAPTER_DEFAULT,
							D3DDEVTYPE_HAL,
							hWnd,
							D3DCREATE_SOFTWARE_VERTEXPROCESSING,
							&d3dpp,
							&mp_d3ddv);

	if (mp_d3ddv == NULL)
	{
		MessageBox(NULL, "Can not create Direct3D Device!", "ERROR", MB_OK);
		return;
	}
}

//Init Direct Input
void CDxManager::InitInput(HWND hWnd, HINSTANCE hInstance)
{
	HRESULT result = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**) &mp_di, NULL);
	if (FAILED(result))
	{
		MessageBox(NULL, "Can not create Direct Input Object!", "ERROR", MB_OK);
		return;
	}

	result = mp_di->CreateDevice(GUID_SysKeyboard, &mp_KeyBoard, NULL);
	if (FAILED(result))
	{
		MessageBox(NULL, "Can not create Direct Input Device!", "ERROR", MB_OK);
		return;
	}

	// Set the data format to "keyboard format" - a predefined data format 
    //
    // A data format specifies which controls on a device we
    // are interested in, and how they should be reported.
    //
    // This tells DirectInput that we will be passing an array
    // of 256 bytes to IDirectInputDevice::GetDeviceState.
	result = mp_KeyBoard->SetDataFormat(&c_dfDIKeyboard);
	if (FAILED(result))
	{
		MessageBox(NULL, "Can not Set Direct Input Device Data Format!", "ERROR", MB_OK);
		return;
	}

	result = mp_KeyBoard->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
	if (FAILED(result))
	{
		MessageBox(NULL, "Can not Set Direct Input Device Cooperative Level!", "ERROR", MB_OK);
		return;
	}


	// IMPORTANT STEP TO USE BUFFERED DEVICE DATA!
    //
    // DirectInput uses unbuffered I/O (buffer size = 0) by default.
    // If you want to read buffered data, you need to set a nonzero
    // buffer size.
    //
    // Set the buffer size to DINPUT_BUFFERSIZE (defined above) elements.
    //
    // The buffer size is a DWORD property associated with the device.

	DIPROPDWORD dipdw;

	dipdw.diph.dwSize		= sizeof(DIPROPDWORD);
	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	dipdw.diph.dwHow		= DIPH_DEVICE;
	dipdw.diph.dwObj		= 0;
	dipdw.dwData			= KEYBOARD_BUFFERED_SIZE;

	result = mp_KeyBoard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);

	result = mp_KeyBoard->Acquire();

	if (FAILED(result))
	{
		MessageBox(NULL, "Can not acquire direct input device!", "ERROR", MB_OK);
		return;
	}
}

//Get methods
//
LPDIRECT3D9 CDxManager::GetDirectObject(void)
{
	return mp_d3d;
}

LPDIRECT3DDEVICE9 CDxManager::GetDirectDevice(void)
{
	return mp_d3ddv;
}

LPDIRECTINPUT8 CDxManager::GetInputObject(void)
{
	return mp_di;
}

LPDIRECTINPUTDEVICE8  CDxManager::GetInputDevice(void)
{
	return mp_KeyBoard;
}